: # *-*-perl-*-*
  eval 'exec perl -S $0 ${1+"$@"}'
    if 0;
#
# Perl script to benchmark various compiler options
# !!! Requires Perl 5 !!!
#

sub scriptname {
#
# Define the name of the script
# Change this if the name of the script is changed!
#
    my $prgname;
    $prgname = "dalton-benchmark";
    $prgname;
}

sub print_help($) {
#
# Calling the script with -h displays help message
#
    my $prgname = shift;
    print "\n$prgname - Script to test performance using various compiler options\n\n";
    print "Usage: $prgname [-h] [-f] -c options-file -t test-list\n\n";
    print "-h\tDisplay this help screen, then quit.\n";
    print "-f\tForce run, do not ask user for confirmation.\n";
    print "-c\tText file comtaining sets of compiler options, each set on a separate line (required).\n";
    print "-t\tComma-separated list of testjobs to be run (required).\n\n";
    exit;
}

#
# Main program
#
use Getopt::Std;
use File::Copy;
use Sys::Hostname;

getopts('hfc:t:');
$prgname = scriptname();
$force = 0;
if ($opt_h) { print_help($prgname) }
$filename = $opt_c;
if ($opt_c eq "") { die "\nPlease specify the filename of the file containing all sets of compiler options\nthat should be benchmarked using the -c option. (i.e. $prgname -c filename ...)\n\n" }
if ($opt_t eq "") { die "\nPlease specify the individual testjobs that should be used for the benchmarking\nby using the -t option followed by a comma-separated list.\n(i.e. $prgname -t test1,test2,test3 ...)\n\n" }
if ($opt_f) { $force = 1 }

#
# Process input and options file
#
open(OPTFILE, $filename) or die("ERROR: $prgname - Sorry, cannot open the file $filename\n");
while (<OPTFILE>) {
    $linein = $_; chop($linein);
    push(@optionset, $linein);
}
close(OPTFILE);
$numopt = scalar(@optionset);
@testjob = split(/,+/, $opt_t);
$numtest = scalar(@testjob);
if (!$force) {
    print "\nFound $numopt sets of compiler options:\n";
    for ($i = 1; $i <= $numopt; $i++) {
	print "Run #$i: $optionset[$i-1]\n";
    }
    print "Is this correct (y/n)? "; $answer = <STDIN>;
    if ($answer ne "y\n" && $answer ne "Y\n") {
	die "\nEdit options-file $filename, then rerun script...\n\n";
    }
#
    print "\nWill benchmark using $numtest testjobs:\n";
    for ($i = 1; $i <= $numtest; $i++) {
	print "Test #$i: $testjob[$i-1]\n";
    }
    print "Is this correct (y/n)? "; $answer = <STDIN>;
    if ($answer ne "y\n" && $answer ne "Y\n") {
	die "\nRerun script using correct set of tests (comma-separated list, no spaces) ...\n\n";
    }
}
else {
    print "\nFound $numopt sets of compiler options.\n";
    print "Will benchmark using $numtest testjobs.\n\n";
}

#
# Read original configuration
#
$testsuite = join ' ', @testjob;
copy("../Makefile.config", "../Makefile.config.backup")
    or die "ERROR: $prgname - Unable to backup Makefile.config";
open(CONFIGFILE, "../Makefile.config")
    or die("ERROR: $prgname - Sorry, cannot open the file Makefile.config\n");
while (<CONFIGFILE>) {
    $linein = $_; chop($linein);
    push(@configline, $linein);
}
close(CONFIGFILE);
$numlines = scalar(@configline);
print "Makefile.config succesfully read ($numlines lines).\n";

#
# Set up benchmark log
#
$benchlog = "benchmark.log";
$host = hostname();
$timedate = localtime(time);

if (!$force && -e $benchlog) {
    print "\nbenchmark.log exists, do you want to overwrite (y/n)? ";
    $answer = <STDIN>;
    if ($answer ne "y\n" && $answer ne "Y\n") {
	die "\nPlease rename benchmark.log, then rerun script...\n\n";
    }
}
open(LOGFILE, ">$benchlog") 
    or die "ERROR: $prgname - Unable to open $benchlog";
print LOGFILE "\n========================================================================\n";
print LOGFILE "===                D A L T O N      B E N C H M A R K                ===\n";
print LOGFILE "========================================================================\n\n";
print LOGFILE "Hostname:\t\t$host\n";
print LOGFILE "Benchmark started:\t$timedate\n";
print LOGFILE "No. compiler options:\t$numopt\n";
print LOGFILE "No. testjobs:\t\t$numtest\n\n";

#
# Loop over all sets of compiler options
#
for ($run = 1; $run <= $numopt; $run++) {
    print "\n *\n*#* Run $run of $numopt: \'$optionset[$run-1]\'\n *\n\n";
    print LOGFILE "------------------------------------------------------------------------\n";
    print LOGFILE "Run $run of $numopt: \'$optionset[$run-1]\'\n";
    print LOGFILE "------------------------------------------------------------------------\n\n";
    $logfile = "benchmark.run$run";
    unlink "../test/$logfile";

    open(CONFIGFILE, ">../Makefile.config")
	or die("ERROR: $prgname - Sorry, cannot open the file Makefile.config\n");
    for ($i = 1; $i <= $numlines; $i++) {
	if (substr($configline[$i-1], 0, 6) eq "FFLAGS") {
	    print CONFIGFILE "FFLAGS        = $optionset[$run-1]\n";
	}
	else {
	    print CONFIGFILE "$configline[$i-1]\n";
	}
    }
    close(CONFIGFILE);
    system ("cd ..; make clean; make") == 0
	or die "ERROR: $prgname - Unable to compile Dalton!\n";
    system ("cd ../test; TEST -log $logfile -benchmark $testsuite") == 0
	or die "ERROR: $prgname - Unable to run test(s)!\n";
    open(TESTLOG, "../test/$logfile")
	or die("ERROR: $prgname - Sorry, cannot open the file ../test/$logfile\n");
    $totaltime = 0.0; $numfail = -1;
#
# Get timings from testlog
#
    while (<TESTLOG>) {
	if (/                              Summary/) {
	    while (<TESTLOG>) {
		if (/ seconds/) {
		    print LOGFILE "$_";
		    @timing = split(/ +/, $_);
		    if ($timing[2] eq "seconds\n") {
			$totaltime = $totaltime + $timing[1];
		    }
		    elsif ($timing[2] eq "minute" || $timing[2] eq "minutes") {
			$totaltime = $totaltime + 60*$timing[1] + $timing[3];
		    }
		    elsif ($timing[2] eq "hour" || $timing[2] eq "hours") {
			$totaltime = $totaltime + 3600*$timing[1] + 60*$timing[3] + $timing[5];
		    }
		}
		elsif (/ALL TESTS ENDED PROPERLY/) { $numfail = 0; }
		elsif (/THERE IS A PROBLEM IN TEST CASE/) {
		    $linein = <TESTLOG>;
		    $numfail = scalar(split(/ +/, $linein));
		}
	    }
	}
    }
    close(TESTLOG);
    print LOGFILE "\nNo. failed tests:\t$numfail\n";
    print LOGFILE "Total time:\t\t$totaltime seconds\n\n\n";

}
close(LOGFILE);
copy("../Makefile.config.backup", "../Makefile.config")
    or die "ERROR: $prgname - Unable to restore Makefile.config";
